#include "log.h"



eComLogDebugLevel MAX_DEBUG_LEVEL = COMLOG_MAX;
LogHook sHook = NULL;
void ComLogSetLevel(eComLogDebugLevel level)
{
   MAX_DEBUG_LEVEL = level;
}



void ComLogSetHook(LogHook hook)
{

   sHook = hook;

}

void ComLogSendToHook(char *str)
{
   if(str != NULL && sHook != NULL)
      {
          sHook(str);   
      }  

}


/*非对外接口*/
void ComLogSendToHook(char *str);

void ComLogHexDump(eComLogDebugLevel level, char *data, int datalen)
{
   char tempbuf[LOG_TEMP_BUF_SIZE] = {0};
   if(level > MAX_DEBUG_LEVEL)
      return ;
   int i = 0, c = 0;
   while (datalen > 0)
    {
        memset(tempbuf, 0, sizeof(tempbuf));
        sprintf(tempbuf+strlen(tempbuf),"0x%lX: ", (long)data);
        for (i = 0;  i < 16;  i++) 
        {
            if (i < datalen) 
            {
                sprintf(tempbuf+strlen(tempbuf),"%02X ", data[i] & 0xFF);
            }
            else 
            {
                sprintf(tempbuf+strlen(tempbuf),"%s", "   ");
            }
            if (i == 7) 
            {
                sprintf(tempbuf+strlen(tempbuf),"%s", " ");
            }
           
        }
        sprintf(tempbuf+strlen(tempbuf),"%s", " |");
        for (i = 0;  i < 16;  i++) {
            if (i < datalen) 
            {
                c = data[i] & 0xFF;
                if ((c < 0x20) || (c >= 0x7F)) 
                   c = '.';
            } else 
            {
                c = ' ';
            }
            sprintf(tempbuf+strlen(tempbuf),"%c", c);
        }
        sprintf(tempbuf+strlen(tempbuf),"%s", "|\n");
        ComLogSendToHook(tempbuf);
        COMLOG_PRINT("%s", tempbuf);
        datalen -= 16;
        data += 16;
    }
    COMLOG_PRINT("\n");
    COMLOG_PRINT("\n");
}


void COMLOG_LOG(const char *tag, const char *file, const char *func, int line, eComLogDebugLevel level, char *fmt, ...) 
{
     static char tempbuf[LOG_TEMP_BUF_SIZE] = {0};
     memset(tempbuf, 0, sizeof(tempbuf));
     va_list vl;
     va_start(vl, fmt);
     if(level <= MAX_DEBUG_LEVEL){  
        #ifdef DEBUG_WITH_TIME
        char timestr[50] = {0};
        struct timespec spec;
        struct tm *timeinfo;
        clock_gettime(CLOCK_REALTIME, &spec);
        timeinfo = localtime(&spec.tv_sec);
        snprintf(timestr, sizeof(timestr), "%04d-%02d-%02d %02d:%02d:%02d.%03ld",
             timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday,
             timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec,
             spec.tv_nsec / 1000000);       
        //remove func  [%s] func
        snprintf(tempbuf, sizeof(tempbuf), "[%s][%d][%s][%s]", file, line,timestr,tag);
        #else
        snprintf(tempbuf, sizeof(tempbuf), "[%s][%d][%s]", file, line, tag);
        #endif
        //vprintf(fmt,  vl); 
        vsnprintf(tempbuf + strlen(tempbuf), sizeof(tempbuf) - strlen(tempbuf), fmt, vl);
        COMLOG_PRINT("%s", tempbuf); 
        ComLogSendToHook(tempbuf);
      }  
     va_end(vl);
}